package com.gimi.cloud.jimi.manage.controller.sys;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gimi.cloud.jimi.common.enums.ResponseCodeEnum;
import com.gimi.cloud.jimi.common.enums.common.RedisKeyEnum;
import com.gimi.cloud.jimi.common.exception.MsgException;
import com.gimi.cloud.jimi.common.utils.JsonUtil;
import com.gimi.cloud.jimi.common.utils.MyBeanUtils;
import com.gimi.cloud.jimi.common.utils.StringUtil;
import com.gimi.cloud.jimi.common.utils.reqhead.Response;
import com.gimi.cloud.jimi.common.utils.reqhead.Util;
import com.gimi.cloud.jimi.dao.dao.sys.SysConfigDao;
import com.gimi.cloud.jimi.dao.redis.IRedisService;
import com.gimi.cloud.jimi.dto.params.*;
import com.gimi.cloud.jimi.dto.sys.SysMasterDTO;
import com.gimi.cloud.jimi.dto.sys.SysMenuDTO;
import com.gimi.cloud.jimi.manage.service.log.LogMasterLoginService;
import com.gimi.cloud.jimi.manage.service.sys.MasterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by shazhiwei on 2017/12/14.
 */
@RestController
@RequestMapping(value = "master")
public class MasterController {
    private final MasterService masterService;
    private final IRedisService iRedisService;
    private static Logger logger = LoggerFactory.getLogger(MasterController.class);
    private final LogMasterLoginService logMasterLoginService;
    private final SysConfigDao configDao;

    public MasterController(MasterService masterService,LogMasterLoginService logMasterLoginService, IRedisService iRedisService,SysConfigDao configDao){
        this.masterService = masterService;
        this.logMasterLoginService = logMasterLoginService;
        this.iRedisService = iRedisService;
        this.configDao = configDao;
    }

    @RequestMapping(value = "/list")
    public void list(@RequestBody MasterListParams params, HttpServletResponse response) {
        Response resp = new Response();
        Map<String, Object> map = new HashMap<>();
        List<SysMasterDTO> list = masterService.getMasterList(params);
        map.put("list", list);
        map.put("count", masterService.getCount(params));
        resp.setRes_data(map);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJSONStringWithDateFormatYYYYMMDDHHMMSS(resp), response);
    }

    @RequestMapping(value = "/single")
    public void single(@RequestBody MasterSingleParams params, HttpServletResponse response) {
        Response resp = new Response();
        SysMasterDTO dto = masterService.getMasterSingle(params);
        resp.setRes_data(dto);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }

    @RequestMapping(value = "/add")
    public void addMaster(@RequestBody AddMasterParams masterDTO, HttpServletResponse response) throws Exception {
        Response resp = new Response();
        masterDTO = masterService.addMaster(masterDTO);
        ResponseCodeEnum codeEnum = masterDTO.getResponseCode();
        if (codeEnum != null) {
            resp.setResponseCode(codeEnum);
        } else {
            resp.setRes_data(ResponseCodeEnum.UNKNOWN_ERROR);
        }
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }

    @RequestMapping(value = "/edit")
    public void edit(@RequestBody AddMasterParams masterDTO, HttpServletResponse response) {
        Response resp = new Response();
        masterDTO = masterService.editMaster(masterDTO);
        ResponseCodeEnum codeEnum = masterDTO.getResponseCode();
        if (codeEnum != null) {
            resp.setResponseCode(codeEnum);
        } else {
            resp.setRes_data(ResponseCodeEnum.UNKNOWN_ERROR);
        }
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }

    @RequestMapping(value = "/delete")
    public void delete(@RequestBody DeleteMasterParams params, HttpServletResponse response) {
        Response resp = new Response();
        if (masterService.deleteMaster(params)) {
            resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        } else {
            resp.setResponseCode(ResponseCodeEnum.UNKNOWN_ERROR);
        }
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }

    @RequestMapping(value = "/login")
    public void login(@RequestBody LoginParams loginVo, HttpServletResponse response) throws Exception{
        Response resp = new Response();
        //获取用户
        SysMasterDTO masterDTO = masterService.getMaster(loginVo);
        if (masterDTO == null) {
            resp.setResponseCode(ResponseCodeEnum.UNKNOWN_ERROR);
            Util.sendResponse(JsonUtil.toJson(resp),response);
        }else{
            if(masterDTO.getResponseCode() != null){
                resp.setResponseCode(masterDTO.getResponseCode());
                Util.sendResponse(JsonUtil.toJson(resp),response);
            }
        }
        //判断用户状态
        if(masterDTO.getMaIsLock() == 1){
            resp.setResponseCode(ResponseCodeEnum.ERR_MASTER_IS_LOCKED);
            Util.sendResponse(JsonUtil.toJson(resp),response);
        }else if (masterDTO.getMaState() == 0){
            resp.setResponseCode(ResponseCodeEnum.ERR_MASTER_STATE);
            Util.sendResponse(JsonUtil.toJson(resp),response);
        }else if (masterDTO.getIsDelete() == 1){
            resp.setResponseCode(ResponseCodeEnum.ERR_MASTER_STATE);
            Util.sendResponse(JsonUtil.toJson(resp),response);
        }else {
            logger.info(String.format("===>用户%s状态正常",loginVo.getUserName()));
        }
        //获取用户权限信息
        Map<String, Object> permission = masterService.getMasterPermissions(masterDTO, masterDTO.getMaId());
        //用户权限信息缓存到redis
        iRedisService.setObject(RedisKeyEnum.JIMI_MASTER_PERMISSION_PRE.getKey() + masterDTO.getMaId(), permission);
        //生成token，并存储在redis中
        String token = masterService.createTokenAndSet2Redis(masterDTO);
        //List<SysMenuDTO> menuList = masterService.getMasterMenuList(masterDTO);
        if (StringUtil.isBlank(token)) {
            resp.setResponseCode(ResponseCodeEnum.MANAGE_JWT_TOKEN_SECRET_ERR);
        } else{
            //根据登录名获取管理员信息
            Map<String,Object> resData = new HashMap<>();
            resData.put("master", masterDTO);
            resData.put("token",token);
            resData.put("permission",permission);
            MyBeanUtils.copyPropertiesIgnoreNullAndEmptyStr(loginVo,masterDTO);
            logMasterLoginService.saveMasterLoginLog(masterDTO,true);
            resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
            resp.setRes_data(resData);
        }
        Util.sendResponse(JsonUtil.toJSONStringWithDateFormatYYYYMMDDHHMMSS(resp),response);
    }

    /**
     * 退出登录
     * @param request
     * @param response
     * @param masterDTO 登录参数
     * @throws Exception
     */
    @PostMapping("/loginOut")
    public Response loginOut(HttpServletRequest request, HttpServletResponse response, @RequestBody SysMasterDTO masterDTO) throws Exception{
        masterDTO.setUsername(masterDTO.getUname());
        Response resp = new Response();
        JSONObject masterTokenRule = iRedisService.getJSONObjectConfigByKey(RedisKeyEnum.JIMI_CONFIG_PRE.getKey() + "manage_token_rule");
        if (null == masterTokenRule) {
            String tokenRule = configDao.getConfigByKey("manage_token_rule");
            if(StringUtil.isBlank(tokenRule)){
                throw new MsgException(ResponseCodeEnum.NO_DATA,"未获取到系统配置参数");
            }
            masterTokenRule= JSON.parseObject(tokenRule);
            iRedisService.setObject(RedisKeyEnum.JIMI_CONFIG_PRE.getKey() + "manage_token_rule",masterTokenRule);
        }
        String isSingleLogin = masterTokenRule.getString("is_single_login");
        //如果当前为单一登录，直接把redis中的登录信息移除掉
        if("1".equals(isSingleLogin)){
            //移除登录用户前缀
            iRedisService.del(RedisKeyEnum.JIMI_MASTER_TOKEN_PRE.getKey() +masterDTO.getUsername());
            iRedisService.del(RedisKeyEnum.JIMI_MASTER_PRE.getKey()+masterDTO.getUid());
        }else{
            //如果当前非单一登录
            //获取用户当前的token信息
            List<String> userTokens = iRedisService.getList(RedisKeyEnum.JIMI_MASTER_TOKEN_PRE.getKey() +masterDTO.getUsername(),String.class);
            if(null != userTokens){
                //移除当前请求token
                userTokens.remove(masterDTO.getAuthToken());
                if(userTokens.size() >0){
                    //更新当前用户的token信息
                    iRedisService.set(RedisKeyEnum.JIMI_MASTER_TOKEN_PRE.getKey() +masterDTO.getUsername(),JsonUtil.toJson(userTokens),masterTokenRule.getLong("validate_times"), TimeUnit.SECONDS);
                }
            }
        }
        SysMasterDTO sysMasterDTO = masterService.load(masterDTO,masterDTO.getUid());
        MyBeanUtils.copyPropertiesIgnoreNullAndEmptyStr(masterDTO,sysMasterDTO);
        logMasterLoginService.saveMasterLoginLog(sysMasterDTO,false);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED,"注销成功");
        return resp;
    }

}
